<template>
  <div id="content" :style="{height:contentHeight+'px'}">
    <Card class="r-n-fs-c">
      <Select v-model="page.type" style="width: 240px;" clearable @on-change="searchClient" placeholder="客户端类型">
        <Option :value=1 selected>WIN客户端-线上版</Option>
        <Option :value=2 selected>WIN客户端-测试版</Option>
        <Option :value=3 selected>安卓客户端-线上版</Option>
        <Option :value=4 selected>安卓客户端-测试版</Option>
      </Select>
      <Select style="width: 240px;margin-left: 5px;" v-model="searchKey" clearable @on-clear="searchKeyClear"
              placeholder="精确匹配查询参数">
        <Option v-for="item in searchParamList" :key="item.key" :value="item.key">{{ item.show }}</Option>
      </Select>
      <Input v-model="searchValue" placeholder="请输入查询内容..." clearable style="width: 300px;margin-left: 5px;"/>
      <Button @click="searchClient(page)" type="primary" style="width: 100px;margin-left: 5px;">查询</Button>
      <div class="client-upload-icon iconfont icon-wenjianshangchuan" @click="showUploadModal"></div>
    </Card>
    <Divider/>
    <div>
      <Table id="card-list-info-table" class="table" stripe
             border
             show-header
             highlight-row
             :loading="isLoading"
             :columns="tableColumns"
             :data="dataList">
      </Table>
      <Divider/>
      <Card style="margin-bottom: 15px;">
        <Page class="r-w-c-c"
              style="width: 100%"
              class-name="card-list-info-page"
              :total="page.total"
              :current="page.pageNum"
              :page-size="page.pageSize"
              @on-change="onPageChange"
              @on-page-size-change="onPageSizeChange"
              show-elevator
              show-sizer
              show-total/>
      </Card>
    </div>
    <Modal v-model="isUploadModalShow" :title="modalTitle">
      <Form ref="ruleValidate" :rules="ruleValidate" :model="operateForm"
            style="margin-left: 0;width: 100%;">
        <label class="r-n-fs-c item-input">
          <span class="item-input-span">完整安装文件</span>
          <div class="r-n-fs-c" style="width: 100%;">
            <Upload
                class="r-n-fs-c"
                paste
                name="file"
                :headers="headers"
                :format="['exe','apk']"
                :show-upload-list=false
                :before-upload="fullClientUploadBefore"
                :action="host + url.file_upload">
              <Button type="default" class="r-n-c-c" :style="{width:'110px',lineHeight: '36px',border:fullClientFile !== null ? 'solid 1px #57A3F3':''}">文件选择
                <div
                    style="width: 24px;height:30px;line-height: 30px;display:inline-block;font-size:13px!important;text-align:center;"
                    class="iconfont icon-wenjianguanli"></div>
              </Button>
              <div style="padding-left: 10px">{{ fullClientFileName }}</div>
            </Upload>
          </div>
        </label>
        <label class="r-n-fs-c item-input">
          <span class="item-input-span">更新安装文件</span>
          <div class="r-n-fs-c" style="width: 100%;">
            <Upload
                class="r-n-fs-c"
                paste
                name="file"
                :headers="headers"
                :format="['exe','apk']"
                :show-upload-list=false
                :before-upload="updateClientUploadBefore"
                :action="host + url.file_upload">
              <Button type="default" class="r-n-c-c" :style="{width:'110px',lineHeight: '36px',border:updateClientFile !== null ? 'solid 1px #57A3F3':''}">文件选择
                <div
                    style="width: 24px;height:30px;line-height: 30px;display:inline-block;font-size:13px!important;text-align:center;"
                    class="iconfont icon-wenjianguanli"></div>
              </Button>
              <div style="padding-left: 10px">{{ updateClientFileName }}</div>
            </Upload>
          </div>
        </label>
        <div class="r-n-fs-c item-input">
          <label class="item-input-span">客户端类型</label>
          <Select v-model="operateForm.type" clearable placeholder="客户端类型">
            <Option :value="1" selected>WIN客户端-线上版</Option>
            <Option :value="2" selected>WIN客户端-测试版</Option>
            <Option :value="3" selected>安卓客户端-线上版</Option>
            <Option :value="4" selected>安卓客户端-测试版</Option>
            <Option :value="5">其他</Option>
          </Select>
        </div>
        <label class="r-n-fs-c item-input">
          <span class="item-input-span">版本号</span>
          <FormItem prop="versionNumber">
            <Input placeholder="版本号" v-model="operateForm.versionNumber"/>
          </FormItem>
        </label>
        <label class="r-n-fs-c item-input">
          <span class="item-input-span">更新说明</span>
          <FormItem prop="description" style="margin-top: 15px;">
            <Input type="textarea" :autosize="{minRows: 2,maxRows: 3}" placeholder="更新说明"
                   v-model="operateForm.description"/>
          </FormItem>
        </label>
      </Form>
      <div slot="footer">
        <Button type="text" @click="isUploadModalShow=false">取消</Button>
        <Button type="primary" @click="modalOk()">确定</Button>
      </div>
    </Modal>
  </div>
</template>

<script>

import {mapGetters, mapState} from "vuex"
import axios from "axios";

export default {
  name: "Client",
  computed: {
    ...mapState(["url", "host", "resourceHost", "realSideWidth"]),
    ...mapGetters(["contentWidth", "contentHeight"]),
  },
  data() {
    return {
      //精准搜索查询字段
      searchKey: 'versionNumber',
      //精准搜索查询字段
      searchValue: null,
      //数据是否在加载中
      isLoading: false,
      //弹出确认操作加载中
      modalLoading: false,
      //弹出框是否显示
      isUploadModalShow: false,
      //是否在更改单页数量
      isPageSizeChanging: false,
      //当前弹出框标题
      modalTitle: '客户端版本上传',
      //弹出框标题集合
      operatorType: ['客户端版本上传', '客户端版本修改'],
      //全量更新文件名称
      fullClientFileName: '未选择',
      //增量更新文件名称
      updateClientFileName: '未选择',
      //全量更新文件
      fullClientFile: null,
      //增量更新文件
      updateClientFile: null,
      //操作参数集合
      operateForm: {
        id: null,
        url: null,
        type: null,
        fullUrl: null,
        description: null,
        versionNumber: null
      },
      //上传客户端参数校验
      ruleValidate: {
        versionNumber: [
          {required: true, type: 'string', message: '版本号不能为空', trigger: 'change'},
          {min: 2, message: '版本号不能少于2个字符', trigger: 'change'},
          {max: 20, message: '版本号不能超过20个字符', trigger: 'change'}
        ],
        description: [
          {required: true, type: 'string', message: '更新描述不能为空', trigger: 'change'},
          {min: 2, message: '更新描述不能少于2个字符', trigger: 'change'},
          {max: 300, message: '更新描述不能超过300个字符', trigger: 'change'}
        ]
      },
      //上传文件
      headers: {
        'u-projectId': null,
        'u-uid': null,
        'u-token': null,
      },
      //分页查询参数
      page: {
        total: 0,
        pageSize: 10,
        pageNum: 1,
        descParams: 'id',
        versionNumber: null,
      },
      //表格结构
      tableColumns: [
        {
          title: 'ID',
          key: 'id',
          width: 100,
          minWidth: 100,
          resizable: true,
          align: "center",
          ellipsis: true,
          sortable: true,
        },
        {
          title: '客户端类型',
          resizable: true,
          minWidth: 180,
          align: "center",
          render: function (createElement, data) {
            let {type} = data.row;
            let typeName;
            switch (type) {
              case 1: typeName = "WIN客户端-线上版";break
              case 2: typeName = "WIN客户端-测试版";break
              case 3: typeName = "安卓客户端-线上版";break
              case 4: typeName = "安卓客户端-测试版";break
              case 5: typeName = "其他";break
              default: {
                typeName = "未知类型";
              }
            }
            return createElement('div', typeName);
          }
        },
        {
          title: '客户端版本',
          key: 'versionNumber',
          resizable: true,
          minWidth: 180,
          align: "center"
        },
        {
          title: '客户端地址',
          key: 'fullUrl',
          resizable: true,
          width: 700,
          minWidth: 100,
          align: "center",
          className: 'r-n-c-c',
        },
        {
          title: '更新描述',
          key: 'description',
          resizable: true,
          width: 300,
          minWidth: 150,
          align: "center",
          render: function (createElement, data) {
            let message = data.row.description;
            if (message !== undefined && message.length > 15) {
              message = message.substring(0, 15) + "...";
            }
            return createElement('div', message)
          }
        },
        {
          title: '上传时间',
          key: 'createTime',
          resizable: true,
          minWidth: 180,
          align: "center"
        },
        {
          title: '操作',
          resizable: true,
          minWidth: 300,
          align: "center",
          render: this.operatorRenderFunction
        }
      ],
      //表格数据
      dataList: [],
      //搜索参数列表
      searchParamList: [
        {
          key: "versionNumber",
          show: "版本号",
        }
      ]
    }
  },
  mounted: function () {
    this.headers['u-projectId'] = localStorage.getItem('u-projectId');
    this.headers['u-uid'] = localStorage.getItem('u-uid');
    this.headers['u-token'] = localStorage.getItem('u-token');
    this.selectPageList(this.page);
  },
  methods: {
    /**
     * 客户端搜索
     */
    searchClient(){
      this.page.pageNum = 1;
      this.selectPageList(this.page);
    },

    /**
     * 搜索参数值清除
     */
    searchKeyClear() {
      let self = this;
      self.searchValue = null;
    },

    /**
     * 显示弹出框
     */
    showUploadModal() {
      this.$refs['ruleValidate'].resetFields();
      this.operateForm.id = null;
      this.operateForm.url = null;
      this.operateForm.fullUrl = null;
      this.operateForm.type = null;
      this.operateForm.versionNumber = null;
      this.operateForm.description = null;
      this.fullClientFileName = '未选择';
      this.updateClientFileName = '未选择';
      this.modalTitle = this.operatorType[0];
      this.isUploadModalShow = true;
    },

    /**
     * 弹出框确认
     */
    modalOk() {
      switch (this.modalTitle) {
        case this.operatorType[0]: {
          this.modalLoading = false;
          this.modalTip = false;
          this.clientUpload();
        }break;
        case this.operatorType[1]: {
          this.modalLoading = false;
          this.modalTip = false;
          this.clientUpdate();
        }break;
      }
    },

    /**
     * 全量安装包文件后缀校验，变量赋值
     * @param e
     * @return {boolean}
     */
    fullClientUploadBefore(e) {
      if (!e.name.endsWith('exe') && !e.name.endsWith('apk')) {
        this.$Notice.warning({
          title: '文件格式错误',
          desc: '文件 ' + e.name + ' 格式不正确，请上传正确格式文件！',
          duration: 10
        });
        return false;
      }
      this.fullClientFile = e;
      this.fullClientFileName = e.name;
      return false;
    },

    /**
     * 增量安装包文件后缀校验，变量赋值
     * @param e
     * @return {boolean}
     */
    updateClientUploadBefore(e) {
      if (!e.name.endsWith('exe') && !e.name.endsWith('apk')) {
        this.$Notice.warning({
          title: '文件格式错误',
          desc: '文件 ' + e.name + ' 格式不正确，请上传正确格式文件！',
          duration: 10
        });
        return false;
      }
      this.updateClientFile = e;
      this.updateClientFileName = e.name;
      return false;
    },

    /**
     * 页数改变重新查询数据
     * @param changedPage
     */
    onPageChange(changedPage) {
      this.page.pageNum = changedPage;
      !this.isPageSizeChanging ? this.selectPageList(this.page) : {};
    },

    /**
     * 单页数量改变查询
     * @param changedPageSize
     */
    onPageSizeChange(changedPageSize) {
      this.isPageSizeChanging = true;
      new Promise(resolve => {
        this.page.pageSize = changedPageSize;
        resolve(changedPageSize)
      }).then(() => {
        this.selectPageList(this.page);
        this.isPageSizeChanging = false;
      })
    },

    /**
     * 操作列渲染
     * @param createElement 便签构建函数
     * @param data 行数据
     * @return {*}
     */
    operatorRenderFunction(createElement, data) {
      let self = this;
      let {fullUrl,url} = data.row;
      let btnList = [];
      btnList.push(createElement('Button', {
        'class': 'button-item',
        style: {
          width: '60px',
          border: '#5CADFF 1px dashed',
          color: '#5cadff'
        },
        attrs: {
          type: "dashed"
        },
        nativeOn: {
          click: function () {
            self.modalTitle = self.operatorType[1];
            self.isUploadModalShow = true;
            let {id,type,fullUrl,url,versionNumber,description} = data.row;
            self.operateForm = {id,type,fullUrl,url,versionNumber,description};
            self.updateClientFile = null;
            self.fullClientFile = null;
            if (fullUrl !== undefined){
              self.fullClientFileName = fullUrl.substring(fullUrl.lastIndexOf('/')+1);
            }else {
              self.fullClientFileName = '未选择';
            }
            if (url !== undefined){
              self.updateClientFileName = url.substring(url.lastIndexOf('/')+1);
            }else {
              self.updateClientFileName = '未选择';
            }
          }
        },
      }, '更改'));
      if (fullUrl !== null) {
        btnList.push(createElement('Button', {
          'class': 'button-item',
          style: {
            width: '60px',
            border: '#5CADFF 1px dashed',
            color: '#5cadff'
          },
          attrs: {
            type: "dashed"
          },
          nativeOn: {
            click: function () {
              window.location.href = fullUrl;
            }
          },
        }, '下载'));
        btnList.push(createElement('Button', {
          'class': 'button-item',
          style: {
            width: '90px',
            border: '#f86d6d 1px dashed',
            color: '#f86d6d'
          },
          attrs: {
            type: "dashed"
          },
          nativeOn: {
            click: function () {
              let input = document.createElement('input');
              input.value = fullUrl;
              document.body.appendChild(input);
              input.select();
              if (document.execCommand('copy')) {
                self.$Message.info("已复制");
              }
              document.body.removeChild(input);
            }
          },
        }, '复制链接'));
      }
      return createElement("div", {'class': 'r-n-c-c'}, [
        createElement('ButtonGroup', btnList),
      ])
    },

    /**
     * 分页查询数据
     * @param selectForm 分页查询表单数据
     */
    selectPageList(selectForm) {
      let self = this;
      let form = Object.assign({}, selectForm);
      if (self.searchKey !== null && self.searchValue !== null && self.searchValue !== "") {
        form[self.searchKey] = self.searchValue.trim();
      }
      self.isLoading = true;
      axios.get(self.url.client_software_list, {params: form}).then(function (response) {
        let {records, total} = response.data.content;
        self.page.total = total;
        self.dataList = records;
        self.isLoading = false;
      }).catch(function () {
        self.isLoading = false;
      });
    },

    /**
     * 全量安装包文件上传
     * @return {Promise<AxiosResponse<any>>}
     */
    fullClientFileUpload() {
      let form = new FormData(),self = this,category;
      if (self.operateForm.type === 1){
        category = 2;
      }else if (self.operateForm.type === 2){
        category = 12;
      }else if (self.operateForm.type === 3){
        category = 13;
      }else if (self.operateForm.type === 4){
        category = 14;
      }else {
        category = 15;
      }
      form.append("category", category);
      form.append("projectId", 1);
      form.append("file", self.fullClientFile);
      return axios.post(self.url.file_upload, form);
    },

    /**
     * 增量安装包文件上传
     * @return {Promise<AxiosResponse<any>>}
     */
    updateClientFileUpload() {
      let form = new FormData(),self = this,category;
      if (self.operateForm.type === 1){
        category = 2;
      }else if (self.operateForm.type === 2){
        category = 12;
      }else if (self.operateForm.type === 3){
        category = 13;
      }else if (self.operateForm.type === 4){
        category = 14;
      }else {
        category = 15;
      }
      form.append("category", category);
      form.append("projectId", 1);
      form.append("file", self.updateClientFile);
      return axios.post(self.url.file_upload, form);
    },

    /**
     * 客户端版本新增操作
     */
    clientUpload() {
      let isValidate = false;
      this.$refs['ruleValidate'].validate((valid) => {
        if (valid) {
          isValidate = true;
        }
      });
      if (!isValidate) {
        return;
      }
      if (this.fullClientFile !== null) {
        let self = this;
        this.$Spin.show({
          render: (h) => {
            return h('div', [
              h('Icon', {
                'class': 'demo-spin-icon-load',
                props: {
                  type: 'ios-loading',
                  size: 18
                }
              }),
              h('div', 'Loading')
            ])
          }
        });
        axios.all([self.fullClientFileUpload(), self.updateClientFileUpload()]).then(self.axios.spread(function (e1, e2) {
          let form2 = Object.assign({}, self.operateForm);
          if (e1.data.state === 200) {
            form2['fullUrl'] = e1.data.content;
            self.$Message.info('完整安装包上传成功!');
          } else {
            self.$Message.info('完整安装包上传失败...');
          }
          if (e2.data.state === 200) {
            form2['url'] = e2.data.content;
            self.$Message.info('更新安装包上传成功!');
          } else {
            self.$Message.info('更新安装包上传失败...');
          }
          axios.post(self.url.client_software_insert, form2).then(function (response) {
            let {state, message} = response.data;
            if (state === 200) {
              self.$Message.success(message);
              self.isUploadModalShow = false;
              self.selectPageList(self.page);
              self.$refs['ruleValidate'].resetFields();
            } else {
              self.$Message.error(message);
              self.isUploadModalShow = false;
              self.$refs['ruleValidate'].resetFields();
            }
          })
          self.$Spin.hide();
        }))
      } else {
        this.$Message.error('文件未选择!')
      }
    },

    /**
     * 客户端版本更新操作
     * @param form
     */
    clientPatch(form){
      let self = this;
      axios.patch(self.url.client_software_modify, form).then(function (response) {
        let {message, state} = response.data;
        if (state === 200) {
          self.$Message.success(message);
          self.isUploadModalShow = false;
          self.selectPageList(self.page);
          self.$refs['ruleValidate'].resetFields();
          self.$Spin.hide();
        }else {
          self.$Message.error(message);
        }
      })
    },

    /**
     * 客户端版本文件更新前上传操作
     */
    clientUpdate() {
      let isValidate = false;
      let self = this;
      this.$refs['ruleValidate'].validate((valid) => {
        if (valid) {
          isValidate = true;
        }
      });
      if (!isValidate) {
        return;
      }
      if (this.fullClientFile === null){
        this.operateForm.fullUrl = null;
      }
      if (this.updateClientFile === null){
        this.operateForm.url = null;
      }
      self.$Spin.show();
      if (this.fullClientFile !== null && this.updateClientFile !== null) {
        axios.all([self.fullClientFileUpload(), self.updateClientFileUpload()]).then(self.axios.spread(function (e1, e2) {
          let form2 = Object.assign({}, self.operateForm);
          if (e1.data.state === 200) {
            form2['fullUrl'] = e1.data.content;
            self.$Message.info('完整安装包上传成功!');
          } else {
            self.$Message.info('完整安装包上传失败...');
          }
          if (e2.data.state === 200) {
            form2['url'] = e2.data.content;
            self.$Message.info('更新安装包上传成功!');
          } else {
            self.$Message.info('更新安装包上传失败...');
          }
          self.$Spin.hide();
          self.clientPatch(form2);
        }))
      }else if (this.fullClientFile === null && this.updateClientFile !== null) {
        let form2 = Object.assign({}, self.operateForm);
        self.updateClientFileUpload().then(e=>{
          if (e.data.state === 200) {
            form2['url'] = e.data.content;
            self.$Message.info('更新安装包上传成功!');
          } else {
            self.$Message.info('更新安装包上传失败...');
          }
          self.$Spin.hide();
          self.clientPatch(form2);
        })
      }else if (this.fullClientFile !== null && this.updateClientFile === null) {
        let form2 = Object.assign({}, self.operateForm);
        self.fullClientFileUpload().then(e=>{
          if (e.data.state === 200) {
            form2['fullUrl'] = e.data.content;
            self.$Message.info('完整安装包上传成功!');
          } else {
            self.$Message.info('完整安装包上传失败...');
          }
          self.$Spin.hide();
          self.clientPatch(form2);
        })
      }else {
        let form2 = Object.assign({}, self.operateForm);
        self.$Spin.hide();
        self.clientPatch(form2);
      }
    }
  }
}
</script>

<style scoped>
#content {
  background: #FFFFFF;
  padding: 15px;
  overflow: auto;
}

.client-upload-icon {
  width: 42px;
  height: 32px;
  line-height: 32px;
  border: solid 1px #e8eaec;
  border-radius: 5px;
  font-size: 20px !important;
  text-align: center;
  margin-left: 5px;
  cursor: pointer;
}

.client-upload-icon:hover {
  background: #DFDFDF78;
}

.item-input {
  height: 45px;
  line-height: 45px;
  margin-bottom: 10px;
}

.item-input-span {
  /*height: inherit;*/
  width: 120px;
}

.item-key {
  /*height: inherit;*/
  width: 150px;
}

.item-value {
  /*height: inherit;*/
  width: 50px;
}

.ivu-form-item-content {
  margin-left: 0 !important;
  position: relative;
  line-height: 32px;
  font-size: 14px;
}

.ivu-form-item {
  margin-bottom: 0;
  width: 100%;
}

.button-item {
  border: #19be6b 1px dashed;
  color: #19be6b;
}

.filter-item {
  margin: 0 5px;
}

.demo-spin-icon-load {
  animation: ani-demo-spin 1s linear infinite;
}

@keyframes ani-demo-spin {
  from {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(180deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.demo-spin-col {
  height: 20px;
  position: relative;
}
</style>
